package com.ermax.aircond.manage.web.bean;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.ermax.aircond.common.parameter.Status;
import com.ermax.aircond.maintain.domain.Building;
import com.ermax.aircond.maintain.domain.Floor;
import com.ermax.aircond.maintain.domain.Machine;
import com.ermax.aircond.maintain.domain.Room;
import com.ermax.aircond.maintain.service.MaintainService;
import com.ermax.aircond.manage.domain.RealTimeControl;
import com.ermax.aircond.manage.service.RealTimeControlService;
import com.ermax.aircond.resource.MessageBundle;

@Scope("view")
@Component
public class RealTimeManageBean implements java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Logger logger = LoggerFactory.getLogger(RealTimeManageBean.class);

	@Resource(name = "maintainService")
	private MaintainService maintainService;
	@Resource(name = "realTimeControlService")
	private RealTimeControlService realTimeControlService;
	@ManagedProperty(value = "#{loginBean.sessionUser}")
	private String sessionUser;

	private Machine selectedMachine;
	private List<RealTimeControl> realTimeControls;
	private RealTimeControl realTimeControl;
	private boolean allowControl = false;

	private List<SelectItem> buildingOptions = new ArrayList<SelectItem>();
	private List<SelectItem> floorOptions = new ArrayList<SelectItem>();
	private List<SelectItem> roomOptions = new ArrayList<SelectItem>();
	private List<SelectItem> machineOptions = new ArrayList<SelectItem>();
	private List<SelectItem> temperatureOptions = new ArrayList<SelectItem>();
	// private List<SelectItem> windValueOptions = new ArrayList<SelectItem>();
	private List<SelectItem> minimumTemperatureOptions = new ArrayList<SelectItem>();
	private long selectedBuildingId;
	private long selectedFloorId;
	private long selectedRoomId;
	private long selectedMachineId;

	//Display for last refresh
	private Date lastRefreshDate = null;
	
	
	@PostConstruct
	public void init() {
		try {
			reset();
		} catch (Exception ex) {
			String message = MessageBundle.getInstance().getMessage("error_init_fail", FacesContext.getCurrentInstance().getViewRoot().getLocale());
			FacesMessage facesMessage = new FacesMessage(message);
			FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		}
	}

	private void reset() throws Exception {
		selectedBuildingId = 0;
		selectedFloorId = 0;
		selectedRoomId = 0;
		selectedMachineId = 0;
		buildingOptions = createBuildingOptions();
		floorOptions = createFloorOptions();
		roomOptions = createRoomOptions();
		machineOptions = createMachineOptions();
		temperatureOptions = createTemperatureOptions();
		// windValueOptions = createWindValueOptions();
		minimumTemperatureOptions = createMinimumTemperatureOptions();
		selectedMachine = new Machine();
		realTimeControl = new RealTimeControl();
		realTimeControls = new ArrayList<RealTimeControl>();
		allowControl = false;
		lastRefreshDate = null;
	}

	public void search() {
		try {
			
			allowControl = false;
			boolean valid = true;

			if (selectedBuildingId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("building_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_building_name", facesMessage);
				valid = false;
			}

			if (selectedFloorId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("floor_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_floor_name", facesMessage);
				valid = false;
			}

			if (selectedRoomId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("room_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_room_name", facesMessage);
				valid = false;
			}

			if (selectedMachineId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("machine_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_machine_name", facesMessage);
				valid = false;
			}

			if (!valid) {
				return;
			}

			if (selectedMachineId > 0) {
				selectedMachine = maintainService.getMachineById(selectedMachineId);
				realTimeControls = realTimeControlService.getRealTimeControls(selectedMachine);
				lastRefreshDate = new Date();
				allowControl = true;
			}

		} catch (Exception ex) {
			String message = MessageBundle.getInstance().getMessage("error_init_fail", FacesContext.getCurrentInstance().getViewRoot().getLocale());
			FacesMessage facesMessage = new FacesMessage(message);
			FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		}
	}

	public void send() {
		try {

			boolean valid = true;

			if (selectedBuildingId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("building_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_building_name", facesMessage);
				valid = false;
			}

			if (selectedFloorId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("floor_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_floor_name", facesMessage);
				valid = false;
			}

			if (selectedRoomId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("room_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_room_name", facesMessage);
				valid = false;
			}

			if (selectedMachineId <= 0) {
				StringBuilder sb = new StringBuilder();
				sb.append(MessageBundle.getInstance().getMessage("machine_name", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				sb.append("-");
				sb.append(MessageBundle.getInstance().getMessage("required_field", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
				FacesMessage facesMessage = new FacesMessage(sb.toString());
				FacesContext.getCurrentInstance().addMessage("search_machine_name", facesMessage);
				valid = false;
			}

			if (!valid) {
				return;
			}

			if (selectedMachineId > 0) {
				selectedMachine = maintainService.getMachineById(selectedMachineId);
				realTimeControlService.sendRealTimeSignal(selectedMachine, realTimeControl);
				
				
				String message = MessageBundle.getInstance().getMessage("info_apply_success", FacesContext.getCurrentInstance().getViewRoot().getLocale());
				FacesMessage facesMessage = new FacesMessage(message);
				FacesContext.getCurrentInstance().addMessage(null, facesMessage);
				allowControl = false;
			}

		} catch (Exception ex) {
			String message = MessageBundle.getInstance().getMessage("error_apply_fail", FacesContext.getCurrentInstance().getViewRoot().getLocale());
			FacesMessage facesMessage = new FacesMessage(message);
			FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		}

	}

	public void buildingValueChanged(ValueChangeEvent event) {
		if (null != event.getNewValue()) {
			selectedFloorId = 0;
			selectedRoomId = 0;
			selectedMachineId = 0;
			selectedBuildingId = (Long) event.getNewValue();
			floorOptions = createFloorOptions();
			roomOptions = createRoomOptions();
			machineOptions = createMachineOptions();
		}
	}

	public void floorValueChanged(ValueChangeEvent event) {
		if (null != event.getNewValue()) {
			selectedRoomId = 0;
			selectedMachineId = 0;
			selectedFloorId = (Long) event.getNewValue();
			roomOptions = createRoomOptions();
			machineOptions = createMachineOptions();
		}
	}

	public void roomValueChanged(ValueChangeEvent event) {		
		if (null != event.getNewValue()) {
			selectedMachineId = 0;
			selectedRoomId = (Long) event.getNewValue();	
			machineOptions = createMachineOptions();
		}
	}
	

	private List<SelectItem> createBuildingOptions() {
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));
		try {
			List<Building> buildings = maintainService.getAllBuildings(Status.ACTIVE);
			for (Building building : buildings) {
				SelectItem item = new SelectItem(building.getBuildingId(), building.getBuildingName());
				results.add(item);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

		return results;
	}

	private List<SelectItem> createFloorOptions() {
		selectedFloorId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));

		try {
			if (selectedBuildingId > 0) {
				Building selectedBuilding = maintainService.getBuildingById(selectedBuildingId);
				List<Floor> floors = maintainService.getFloors(selectedBuilding, null, Status.ACTIVE);
				for (Floor floor : floors) {
					SelectItem item = new SelectItem(floor.getFloorId(), floor.getFloorName());
					results.add(item);
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return results;
	}

	private List<SelectItem> createRoomOptions() {
		selectedRoomId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));
		try {
			if (selectedFloorId > 0) {
				Floor selectedFloor = maintainService.getFloorById(selectedFloorId);
				List<Room> rooms = maintainService.getRooms(null, selectedFloor, null, Status.ACTIVE);
				for (Room room : rooms) {
					SelectItem item = new SelectItem(room.getRoomId(), room.getRoomName());
					results.add(item);
				}
			}
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
		}
		return results;
	}

	
	private List<SelectItem> createMachineOptions() {
		selectedMachineId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		results.add(new SelectItem(0, "------"));
		try {
			if (selectedRoomId > 0) {
				Room selectedRoom = maintainService.getRoomById(selectedRoomId);
				List<Machine> machines = maintainService.getMachines(null, null, selectedRoom, null, Status.ACTIVE);
				for (Machine machine : machines) {
					SelectItem item = new SelectItem(machine.getMachineId(), machine.getMachineName());
					results.add(item);
				}
			}
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
		}
		return results;
	}
	
	private List<SelectItem> createTemperatureOptions() {
		List<SelectItem> results = new ArrayList<SelectItem>();
		for (int i = 16; i <= 30; i++) {
			results.add(new SelectItem(i, String.valueOf(i)));
		}
		return results;
	}

	/*
	 * private List<SelectItem> createWindValueOptions(){ List<SelectItem>
	 * results = new ArrayList<SelectItem>(); int i = 0; while(i <= 100){
	 * results.add(new SelectItem(i,String.valueOf(i))); i += 5; }
	 * 
	 * return results; }
	 */
	private List<SelectItem> createMinimumTemperatureOptions() {
		List<SelectItem> results = new ArrayList<SelectItem>();
		//results.add(new SelectItem(0, "NONE"));
		for (int i = 16; i <= 30; i++) {
			results.add(new SelectItem(i, String.valueOf(i)));
		}

		return results;
	}

	public MaintainService getMaintainService() {
		return maintainService;
	}

	public void setMaintainService(MaintainService maintainService) {
		this.maintainService = maintainService;
	}

	public String getSessionUser() {
		return sessionUser;
	}

	public void setSessionUser(String sessionUser) {
		this.sessionUser = sessionUser;
	}
	

	public List<SelectItem> getBuildingOptions() {
		return buildingOptions;
	}

	public void setBuildingOptions(List<SelectItem> buildingOptions) {
		this.buildingOptions = buildingOptions;
	}

	public List<SelectItem> getFloorOptions() {
		return floorOptions;
	}

	public void setFloorOptions(List<SelectItem> floorOptions) {
		this.floorOptions = floorOptions;
	}

	public List<SelectItem> getRoomOptions() {
		return roomOptions;
	}

	public void setRoomOptions(List<SelectItem> roomOptions) {
		this.roomOptions = roomOptions;
	}

	public long getSelectedBuildingId() {
		return selectedBuildingId;
	}

	public void setSelectedBuildingId(long selectedBuildingId) {
		this.selectedBuildingId = selectedBuildingId;
	}

	public long getSelectedFloorId() {
		return selectedFloorId;
	}

	public void setSelectedFloorId(long selectedFloorId) {
		this.selectedFloorId = selectedFloorId;
	}

	public long getSelectedRoomId() {
		return selectedRoomId;
	}

	public void setSelectedRoomId(long selectedRoomId) {
		this.selectedRoomId = selectedRoomId;
	}

	public boolean isAllowControl() {
		return allowControl;
	}

	public void setAllowControl(boolean allowControl) {
		this.allowControl = allowControl;
	}

	public List<RealTimeControl> getRealTimeControls() {
		try {
			if (selectedMachineId > 0) {
				realTimeControls = realTimeControlService.getRealTimeControls(selectedMachine);
			}
		} catch (Exception e) {}
		
		return realTimeControls;
	}

	public void setRealTimeControls(List<RealTimeControl> realTimeControls) {
		this.realTimeControls = realTimeControls;
	}

	public RealTimeControlService getRealTimeControlService() {
		return realTimeControlService;
	}

	public void setRealTimeControlService(RealTimeControlService realTimeControlService) {
		this.realTimeControlService = realTimeControlService;
	}

	public List<SelectItem> getTemperatureOptions() {
		return temperatureOptions;
	}

	public void setTemperatureOptions(List<SelectItem> temperatureOptions) {
		this.temperatureOptions = temperatureOptions;
	}

	public List<SelectItem> getMinimumTemperatureOptions() {
		return minimumTemperatureOptions;
	}

	public void setMinimumTemperatureOptions(List<SelectItem> minimumTemperatureOptions) {
		this.minimumTemperatureOptions = minimumTemperatureOptions;
	}

	/*
	 * public List<SelectItem> getWindValueOptions() { return windValueOptions;
	 * }
	 * 
	 * public void setWindValueOptions(List<SelectItem> windValueOptions) {
	 * this.windValueOptions = windValueOptions; }
	 */
	public RealTimeControl getRealTimeControl() {
		return realTimeControl;
	}

	public void setRealTimeControl(RealTimeControl realTimeControl) {
		this.realTimeControl = realTimeControl;
	}

	public Machine getSelectedMachine() {
		return selectedMachine;
	}

	public void setSelectedMachine(Machine selectedMachine) {
		this.selectedMachine = selectedMachine;
	}

	public long getSelectedMachineId() {
		return selectedMachineId;
	}

	public void setSelectedMachineId(long selectedMachineId) {
		this.selectedMachineId = selectedMachineId;
	}

	public List<SelectItem> getMachineOptions() {
		return machineOptions;
	}

	public void setMachineOptions(List<SelectItem> machineOptions) {
		this.machineOptions = machineOptions;
	}

	public Date getLastRefreshDate() {
		if (selectedMachineId > 0) {
			lastRefreshDate =  new Date();
			
		}
		return lastRefreshDate;
	}

	public void setLastRefreshDate(Date lastRefreshDate) {
		this.lastRefreshDate = lastRefreshDate;
	}

}
